package com.taotaojs.util.excel;

import com.taotaojs.exception.MyInnerException;
import com.taotaojs.util.CollectionUtil;
import com.taotaojs.util.ConstantUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

/**
 * 表格工具类
 * @author: TaoTaojs
 * @Date: 2019/4/24 18:22
 * @Description:
 * 表格工具类
 * @关联类:
 */
public class SheetUtils {

    SheetUtils(){}

    /**
     * 获取合并单元格的值
     * @param cell
     * @return
     */
    public static String getMergedRegionValue(Cell cell){
        if(cell != null) {
            cell.setCellType(CellType.STRING);
            Sheet sheet = cell.getSheet();
            String value = null;
            //获得该sheet所有合并单元格数量
            int sheetMergeCount = sheet.getNumMergedRegions();

            for(int i = 0 ; i < sheetMergeCount ; i++){
                // 获得合并区域
                CellRangeAddress ca = sheet.getMergedRegion(i);

                //判断传入的单元格的行号列号是否在合并单元格的范围内，如果在合并单元格的范围内，择返回合并区域的个单元格格值
                if(isMergedRegion(ca, cell)){
                    Row fRow = sheet.getRow(ca.getFirstRow());
                    Cell fCell = fRow.getCell(ca.getFirstColumn());
                    value = getCellValue(fCell) ;
                }
            }
            //如果该单元格行号列号不在任何一个合并区域，则返回原值
            return value == null ? cell.getStringCellValue() : value;
        }
        return null;
    }

    /**
     * 判断是否为合并的单元格区域
     * @param sheet
     * @param row
     * @param column
     * @return
     */
    public static boolean isMergedRow(Sheet sheet,int row ,int column) {
        int sheetMergeCount = sheet.getNumMergedRegions();
        for (int i = 0; i < sheetMergeCount; i++) {
            CellRangeAddress range = sheet.getMergedRegion(i);
            int firstColumn = range.getFirstColumn();
            int lastColumn = range.getLastColumn();
            int firstRow = range.getFirstRow();
            int lastRow = range.getLastRow();
            if(row == firstRow && row == lastRow && column >= firstColumn && column <= lastColumn){
                return true;
            }
        }
        return false;
    }

    /**
     * 判断多个单元格是否是同一个合并的单元格
     * @param sheet
     * @param cells
     * @return
     */
    public static boolean isEqualMergedRegion(Sheet sheet, Cell... cells){
        if(CollectionUtil.isEmpty(cells) || sheet == null || cells[0] == null){
            return false;
        }
        //找到第一个cell对应的合并单元格区域
        Cell oneCell = cells[0];
        CellRangeAddress rangeUp = null;
        for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
            CellRangeAddress range = sheet.getMergedRegion(i);
            if(isMergedRegion(range, oneCell)){
                rangeUp = range;
                break;
            }
        }
        //如果没有找到就说明第一个都不是合并单元格，输出的结果肯定为false
        if(rangeUp == null){
            return false;
        }
        //如果找到了，就根据这个单元格区域，查询剩下的cell是否在这个区域里面，如果有不存在的就输出false（忽略第一个元素）
        for (int i = 1; i < cells.length; i++) {
            Cell cell = cells[i];
            if(!isMergedRegion(rangeUp, cell)){
                return false;
            }
        }
        return true;
    }

    /**
     * 判断单元格是否存在于这个合并区域中
     * @param range
     * @param cell
     * @return
     */
    public static boolean isMergedRegion(CellRangeAddress range, Cell cell) {
        int firstColumn = range.getFirstColumn();
        int lastColumn = range.getLastColumn();
        int firstRow = range.getFirstRow();
        int lastRow = range.getLastRow();
        int row = cell.getRowIndex();
        int column = cell.getColumnIndex();
        if(row >= firstRow && row <= lastRow && column >= firstColumn && column <= lastColumn){
            return true;
        }
        return false;
    }

    /**
     * 判断sheet页中是否含有合并单元格
     * @param sheet
     * @return
     */
    private static boolean hasMerged(Sheet sheet) {
        return sheet.getNumMergedRegions() > 0;
    }

    /**
     * 添加合并单元格
     * @param sheet
     * @param firstRow 开始行
     * @param lastRow 结束行
     * @param firstCol 开始列
     * @param lastCol 结束列
     */
     public static void mergeRegion(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) {
        sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
    }

    /**
     * 获取单元格的值
     * @param cell
     * @return
     */
    protected static String getCellValue(Cell cell){
        if(cell == null) {
            return "";
        }

        Object type = cell.getCellTypeEnum();
        if(type instanceof Integer){
            if(type.equals(ConstantUtil.ONE)) {
                return cell.getStringCellValue();
            } else if(type.equals(ConstantUtil.FOUR)) {
                return String.valueOf(cell.getBooleanCellValue());
            } else if(type.equals(ConstantUtil.TWO)) {
                return cell.getCellFormula() ;
            } else if(type.equals(ConstantUtil.ZERO)) {
                return String.valueOf(cell.getNumericCellValue());
            }
        }else if(type instanceof CellType){
            if(type == CellType.STRING) {
                return cell.getStringCellValue();
            } else if(type == CellType.BOOLEAN) {
                return String.valueOf(cell.getBooleanCellValue());
            } else if(type == CellType.FORMULA) {
                return cell.getCellFormula() ;
            } else if(type == CellType.NUMERIC) {
                return String.valueOf(cell.getNumericCellValue());
            }
        }

        return "";
    }

    /**
     * 类型转换
     *
     * @param classzz
     * @param value
     * @return
     */
    protected static Object convertType(Class<?> classzz, String value) {
        if (String.class == classzz){
            return value;
        }
        if (Character.class == classzz || char.class == classzz) {
            return value.charAt(0);
        }
        if (Boolean.class == classzz || boolean.class == classzz) {
            return Boolean.valueOf(value.toLowerCase());
        }
        return convertTypeNumber(classzz, value);

    }

    /**
     * 数字类型的转换方法
     * @param classzz
     * @param value
     * @param <T>
     * @return
     */
    protected static<T> Object convertTypeNumber(Class<T> classzz, String value) {
        if (Integer.class == classzz || int.class == classzz) {
            return Integer.valueOf(value);
        }
        if (Short.class == classzz || short.class == classzz) {
            return Short.valueOf(value);
        }
        if (Byte.class == classzz || byte.class == classzz) {
            return Byte.valueOf(value);
        }
        if (Long.class == classzz || long.class == classzz) {
            return Long.valueOf(value);
        }
        if (Float.class == classzz || float.class == classzz) {
            return Float.valueOf(value);
        }
        if (Double.class == classzz || double.class == classzz) {
            return Double.valueOf(value);
        }
        throw new MyInnerException("没有此类型，请手动设置：" + classzz.getClass().toString());
    }

}
